<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>销售数据可视化仪表盘</title>

    <!-- 本地 ECharts 与 Axios -->
    <script src="./js/echarts.js"></script>
    <script src="./js/axios.min.js"></script>

    <!-- FontAwesome CDN（可离线化） -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"/>

    <!-- ============  样 式 表 ============ -->
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #1a2a6c, #2a4d69, #4b86b4);
            color: #fff;
            min-height: 100vh;
            padding-bottom: 80px;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
            padding: 20px;
        }
        
        header {
            text-align: center;
            padding: 20px 0;
            margin-bottom: 30px;
            border-bottom: 2px solid rgba(255, 255, 255, 0.1);
        }
        
        h1 {
            font-size: 2.8rem;
            margin-bottom: 10px;
            text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
            background: linear-gradient(to right, #ff7e5f, #feb47b);
            -webkit-background-clip: text;
            background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        
        .subtitle {
            font-size: 1.2rem;
            opacity: 0.8;
            max-width: 800px;
            margin: 0 auto;
            line-height: 1.6;
        }
        
        .dashboard {
            display: grid;
            grid-template-columns: 1fr;
            gap: 25px;
            margin-bottom: 30px;
            min-height: 600px;
        }
        
        .chart-container {
            background: rgba(255, 255, 255, 0.08);
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            height: 100%;
        }
        
        .chart-title {
            font-size: 1.6rem;
            margin-bottom: 25px;
            display: flex;
            align-items: center;
            color: #ffb74d;
            padding-bottom: 15px;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .chart-title i {
            margin-right: 15px;
            font-size: 1.8rem;
        }
        
        .chart {
            width: 100%;
            height: 500px;
        }
        
        .page-indicator {
            display: flex;
            justify-content: center;
            margin: 20px 0;
            gap: 10px;
        }
        
        .page-dot {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.3);
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .page-dot.active {
            background: #ffb74d;
            transform: scale(1.2);
        }
        
        .navigation {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            background: rgba(0, 10, 30, 0.9);
            backdrop-filter: blur(5px);
            display: flex;
            justify-content: center;
            padding: 15px;
            border-top: 1px solid rgba(255, 255, 255, 0.1);
            z-index: 100;
        }
        
        .nav-btn {
            background: rgba(255, 255, 255, 0.1);
            border: none;
            color: #fff;
            padding: 12px 25px;
            margin: 0 10px;
            border-radius: 30px;
            cursor: pointer;
            font-size: 1.1rem;
            display: flex;
            align-items: center;
            transition: all 0.3s ease;
        }
        
        .nav-btn:hover {
            background: rgba(255, 183, 77, 0.2);
            transform: translateY(-3px);
        }
        
        .nav-btn i {
            margin-right: 8px;
        }
        
        .page-description {
            max-width: 800px;
            margin: 0 auto 25px;
            padding: 15px;
            background: rgba(0, 0, 0, 0.15);
            border-radius: 10px;
            line-height: 1.6;
        }
        
        .page {
            display: none;
        }
        
        .page.active {
            display: block;
            animation: fadeIn 0.5s ease;
        }
        
        .insight-container {
            display: flex;
            gap: 20px;
            margin-top: 20px;
        }
        
        .insight-card {
            background: rgba(255, 255, 255, 0.05);
            border-radius: 10px;
            padding: 15px;
            flex: 1;
            display: flex;
            align-items: flex-start;
            gap: 15px;
        }
        
        .insight-card i {
            font-size: 1.8rem;
            color: #ffb74d;
            margin-top: 5px;
        }
        
        .insight-content h4 {
            margin-bottom: 10px;
            font-size: 1.2rem;
        }
        
        .insight-content ul {
            list-style: disc;
            padding-left: 20px;
            line-height: 1.8;
        }
        
        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }
        
        @media (max-width: 768px) {
            .nav-btn {
                padding: 10px 15px;
                font-size: 0.9rem;
            }
            .nav-btn span {
                display: none;
            }
            .nav-btn i {
                margin-right: 0;
            }
            h1 {
                font-size: 2.2rem;
            }
            .chart {
                height: 400px;
            }
        }
    </style>
</head>

<body>
<div class="container">
    <header>
        <h1>销售数据可视化仪表盘</h1>
        <p class="subtitle">基于多维度销售数据的分析展示，通过底部导航栏在不同分析视图间切换</p>
    </header>

    <div class="dashboard">
        <!-- 1. 畅销商品 -->
        <div class="page active" id="page1">
            <div class="page-description">
                <h3><i class="fas fa-star"></i> 畅销商品分析</h3>
                <p>展示销量最高的 10 个商品及其销售数量，帮助识别最受欢迎的产品。</p>
            </div>
            <div class="chart-container">
                <div class="chart-title"><i class="fas fa-trophy"></i> 销量最高的 10 个商品</div>
                <div id="productChart" class="chart"></div>
            </div>
        </div>

        <!-- 2. 周销售趋势 -->
        <div class="page" id="page2">
            <div class="page-description">
                <h3><i class="fas fa-chart-line"></i> 周销售趋势分析</h3>
                <p>展示全年 52 周的销售数据，包括每周收入、订单数量和平均订单价值。</p>
            </div>
            <div class="chart-container">
                <div class="chart-title"><i class="fas fa-calendar-week"></i> 周销售趋势分析</div>
                <div id="weeklyChart" class="chart"></div>
            </div>
        </div>

        <!-- 3. 国家订单分析 -->
        <div class="page" id="page3">
            <div class="page-description">
                <h3><i class="fas fa-globe-europe"></i> 国家订单分析</h3>
                <p>展示各国的购买订单量和退货订单量，帮助分析不同国家的退货率。</p>
            </div>
            <div class="chart-container">
                <div class="chart-title"><i class="fas fa-exchange-alt"></i> 各国购买与退货订单分析</div>
                <div id="orderChart" class="chart"></div>
            </div>
        </div>

        <!-- 4. 关键词分析 -->
        <div class="page" id="page4">
            <div class="page-description">
                <h3><i class="fas fa-key"></i> 产品关键词分析</h3>
                <p>展示产品描述中最常出现的关键词，帮助了解产品特征和消费者偏好。</p>
            </div>
            <div class="chart-container">
                <div class="chart-title"><i class="fas fa-tags"></i> 热门关键词分析</div>
                <div id="keywordChart" class="chart"></div>
            </div>
        </div>

        <!-- 5. 国家销售分布 -->
        <div class="page" id="page5">
            <div class="page-description">
                <h3><i class="fas fa-map-marked-alt"></i> 国家销售分布</h3>
                <p>展示各个国家的总销售额分布，帮助识别主要销售市场。</p>
            </div>
            <div class="chart-container">
                <div class="chart-title"><i class="fas fa-globe-americas"></i> 各国销售分布</div>
                <div id="countrySalesChart" class="chart"></div>
            </div>
        </div>

        <!-- 6. 商品单价 vs 销量 -->
        <div class="page" id="page6">
            <div class="page-description">
                <h3><i class="fas fa-dollar-sign"></i> 商品平均单价与销售关系分析</h3>
                <p>
                    通过散点图直观呈现价格与销量的相关性，帮助制定合理定价策略。
                </p>
                <div class="insight-container">
                    <div class="insight-card">
                        <i class="fas fa-lightbulb"></i>
                        <div class="insight-content">
                            <h4>关键洞察</h4>
                            <ul>
                                <li>价格在 20–40 元区间的商品销量最高，占总销量的 45%</li>
                                <li>单价超过 80 元的商品销量极低，仅占总销量的 5%</li>
                                <li>存在价格弹性拐点，约为 50 元，超过此价格销量显著下降</li>
                            </ul>
                        </div>
                    </div>
                    <div class="insight-card">
                        <i class="fas fa-chart-line"></i>
                        <div class="insight-content">
                            <h4>策略建议</h4>
                            <ul>
                                <li>对销量低迷的高价商品进行促销或捆绑销售</li>
                                <li>考虑推出 40–60 元区间的新产品，平衡利润与销量</li>
                                <li>对价格敏感型商品实施动态定价策略</li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
            <div class="chart-container">
                <div class="chart-title"><i class="fas fa-chart-scatter"></i> 商品平均单价与销售关系</div>
                <div id="priceSalesChart" class="chart"></div>
            </div>
        </div>

        <!-- 页面指示器 & 导航按钮 -->
        <div class="page-indicator">
            <div class="page-dot active" data-page="1"></div>
            <div class="page-dot" data-page="2"></div>
            <div class="page-dot" data-page="3"></div>
            <div class="page-dot" data-page="4"></div>
            <div class="page-dot" data-page="5"></div>
            <div class="page-dot" data-page="6"></div>
        </div>

        <div class="navigation">
            <button class="nav-btn" id="prev-btn"><i class="fas fa-arrow-left"></i><span>上一页</span></button>
            <button class="nav-btn" id="next-btn"><i class="fas fa-arrow-right"></i><span>下一页</span></button>
        </div>
    </div>
</div>

<!-- ============ 页 面 逻 辑 ============ -->
<script>
    /* ---------- 基础配置 ---------- */
    const API_BASE_URL = 'http://192.168.147.68:8080';   // 统一修改处
    let currentPage = 1;
    const totalPages  = 6;

    /* ---------- 页面切换 ---------- */
    function initNavigation() {
        // 按钮
        document.getElementById('prev-btn').addEventListener('click', () => {
            if (currentPage > 1) switchPage(currentPage - 1);
        });
        document.getElementById('next-btn').addEventListener('click', () => {
            if (currentPage < totalPages) switchPage(currentPage + 1);
        });
        // 小圆点
        document.querySelectorAll('.page-dot').forEach(dot => {
            dot.addEventListener('click', () => {
                switchPage(parseInt(dot.dataset.page));
            });
        });
    }

    function switchPage(pageNum) {
        // 隐藏旧页
        document.getElementById(`page${currentPage}`).classList.remove('active');
        document.querySelector(`.page-dot[data-page="${currentPage}"]`).classList.remove('active');

        // 显示新页
        document.getElementById(`page${pageNum}`).classList.add('active');
        document.querySelector(`.page-dot[data-page="${pageNum}"]`).classList.add('active');

        currentPage = pageNum;

        // 按需初始化图表
        initPageCharts(pageNum);
    }

    /* ---------- 初始化当前页图表 ---------- */
    function initPageCharts(page) {
        switch (page) {
            case 1: if (!window.productChartInitialized) { initProductChart();          window.productChartInitialized = true; } break;
            case 2: if (!window.weeklyChartInitialized)  { initWeeklyChart();           window.weeklyChartInitialized  = true; } break;
            case 3: if (!window.orderChartInitialized)   { initOrderChart();            window.orderChartInitialized   = true; } break;
            case 4: if (!window.keywordChartInitialized) { initKeywordChart();          window.keywordChartInitialized = true; } break;
            case 5: if (!window.countrySalesChartInitialized) { initCountrySalesChart();window.countrySalesChartInitialized = true; } break;
            case 6: if (!window.priceSalesChartInitialized) { initPriceSalesChart();    window.priceSalesChartInitialized = true; } break;
        }
    }

    /* ---------- 图表实现 ---------- */
    /* 1. 畅销商品 TOP10 */
function initProductChart() {
    const chart = echarts.init(document.getElementById('productChart'));
    axios.get(`${API_BASE_URL}/api/top10_products/list`)
        .then(res => {
            const data = (res.data?.data) || [];  // ✅ 取真正数组
            const option = {
                tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, formatter: '{b}: {c} 件' },
                grid: { left: '3%', right: '4%', bottom: '3%', top: '10%', containLabel: true },
                xAxis: {
                    type: 'value',
                    name: '销售数量',
                    nameTextStyle: { color: '#ccc' },
                    axisLine: { lineStyle: { color: '#aaa' } },
                    axisLabel: { color: '#ccc' },
                    splitLine: { lineStyle: { color: 'rgba(255,255,255,.1)' } }
                },
                yAxis: {
                    type: 'category',
                    data: data.map(i => i.description),
                    axisLine: { lineStyle: { color: '#aaa' } },
                    axisLabel: { color: '#ccc' }
                },
                series: [{
                    name: '销量',
                    type: 'bar',
                    data: data.map(i => i.totalQuantity),
                    itemStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                            { offset: 0, color: '#83bff6' },
                            { offset: 0.5, color: '#188df0' },
                            { offset: 1, color: '#188df0' }
                        ])
                    },
                    label: { show: true, position: 'right', color: '#e0e0e0', formatter: '{c} 件' }
                }]
            };
            chart.setOption(option);
            window.addEventListener('resize', () => chart.resize());
        })
        .catch(err => console.error('畅销商品数据失败:', err));
}

    /* 2. 周销售趋势（沿用你给的字段名） */
    function initWeeklyChart() {
        const chart = echarts.init(document.getElementById('weeklyChart'));
        axios.get(`${API_BASE_URL}/api/weekly_sales_trend/list`)
            .then(res => {
                const data = (res.data?.data) || [];
                const weeks = data.map(d => d.yearWeek);
                const revenue = data.map(d => d.weeklyRevenue);
                const orders  = data.map(d => d.weeklyOrders);
                const avg     = data.map(d => (d.weeklyRevenue / d.weeklyOrders).toFixed(2));

                const option = {
                    tooltip:{
                        trigger:'axis',axisPointer:{type:'cross'},
                        formatter: p => `
                            周数: ${p[0].name}<br/>
                            销售额: ¥${p[0].value.toLocaleString()}<br/>
                            订单数: ${p[1].value.toLocaleString()}<br/>
                            平均订单价值: ¥${p[2].value}`
                    },
                    legend:{data:['周销售额','订单数量','平均订单价值'],textStyle:{color:'#e0e0e0'},bottom:10},
                    grid:{left:'3%',right:'4%',bottom:'15%',top:'15%',containLabel:true},
                    xAxis:{type:'category',boundaryGap:false,data:weeks,axisLine:{lineStyle:{color:'#aaa'}},axisLabel:{color:'#ccc',interval:4}},
                    yAxis:[
                        {type:'value',name:'销售额',axisLabel:{formatter:'¥{value}',color:'#ccc'},nameTextStyle:{color:'#ccc'},splitLine:{lineStyle:{color:'rgba(255,255,255,.1)'}}},
                        {type:'value',name:'订单/平均价值',axisLabel:{color:'#ccc'},nameTextStyle:{color:'#ccc'},splitLine:{show:false}}
                    ],
                    series:[
                        {name:'周销售额',type:'line',smooth:true,lineStyle:{width:4,color:'#5470c6'},areaStyle:{color:new echarts.graphic.LinearGradient(0,0,0,1,[
                            {offset:0,color:'rgba(84,112,198,.5)'},
                            {offset:1,color:'rgba(84,112,198,.1)'}
                        ])
                    },data:revenue
                },
                        {name:'订单数量',type:'bar',yAxisIndex:1,barWidth:'60%',itemStyle:{color:'#91cc75'},data:orders},
                        {name:'平均订单价值',type:'line',smooth:true,yAxisIndex:1,lineStyle:{width:3,color:'#fac858'},symbol:'circle',symbolSize:8,data:avg}
                    ]
                };
                chart.setOption(option);
                window.addEventListener('resize', () => chart.resize());
            })
            .catch(err => console.error('周销售趋势数据失败:', err));
    }

    /* 3. 国家订单 & 退货 */
function initOrderChart() {
    const chart = echarts.init(document.getElementById('orderChart'));
    axios.get(`${API_BASE_URL}/api/country_order_return/list`)
        .then(res => {
            const data = (res.data?.data) || [];
            const option = {
                tooltip: {
                    trigger: 'axis',
                    axisPointer: { type: 'shadow' },
                    formatter: p => {
                        const buy = p[0], ret = p[1];
                        const rate = (ret.value / buy.value * 100).toFixed(1);
                        return `${buy.name}<br/>购买订单: ${buy.value.toLocaleString()}<br/>退货订单: ${ret.value.toLocaleString()}<br/>退货率: ${rate}%`;
                    }
                },
                legend: {
                    data: ['购买订单量', '退货订单量'],
                    textStyle: { color: '#e0e0e0' },
                    bottom: 10
                },
                grid: {
                    left: '3%', right: '4%', bottom: '15%', top: '10%', containLabel: true
                },
                xAxis: {
                    type: 'category',
                    data: data.map(i => i.country),            // ← 驼峰 country
                    axisLabel: { interval: 0, rotate: 30, color: '#ccc' },
                    axisLine: { lineStyle: { color: '#aaa' } }
                },
                yAxis: {
                    type: 'value',
                    name: '订单数量',
                    axisLine: { lineStyle: { color: '#aaa' } },
                    axisLabel: { color: '#ccc' },
                    splitLine: { lineStyle: { color: 'rgba(255,255,255,.1)' } }
                },
                series: [
                    {
                        name: '购买订单量',
                        type: 'bar',
                        stack: 'total',
                        data: data.map(i => i.normalOrders),     // ← 驼峰 normalOrders
                        itemStyle: { color: '#5470c6' }
                    },
                    {
                        name: '退货订单量',
                        type: 'bar',
                        stack: 'total',
                        data: data.map(i => i.returnOrders),     // ← 驼峰 returnOrders
                        itemStyle: { color: '#ee6666' }
                    }
                ]
            };
            chart.setOption(option);
            window.addEventListener('resize', () => chart.resize());
        })
        .catch(err => console.error('国家订单数据失败:', err));
}

    /* 4. 热门关键词 */
    function initKeywordChart() {
    const chart = echarts.init(document.getElementById('keywordChart'));
    axios.get(`${API_BASE_URL}/api/hot_keywords/list`)
        .then(res => {
            const data = (res.data?.data) || [];
            const option = {
                tooltip:{trigger:'item',formatter:'{b}: {c} 次'},
                grid:{left:'3%',right:'4%',bottom:'3%',top:'10%',containLabel:true},
                xAxis:{type:'category',data:data.map(i=>i.keyword),axisLabel:{interval:0,rotate:45,color:'#ccc'},axisLine:{lineStyle:{color:'#aaa'}}},
                yAxis:{type:'value',name:'出现次数',axisLine:{lineStyle:{color:'#aaa'}},axisLabel:{color:'#ccc'},splitLine:{lineStyle:{color:'rgba(255,255,255,.1)'}}},
                series:[{
                    name:'出现次数',type:'bar',data:data.map(i=>i.keywordCount),  // ✅ 改成 keywordCount
                    itemStyle:{color:new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:'#ff9a9e'},{offset:1,color:'#fad0c4'}])}
                }]
            };
            chart.setOption(option);
            window.addEventListener('resize', () => chart.resize());
        })
        .catch(err => console.error('关键词数据失败:', err));
}

    /* 5. 国家销售额分布 */

function initCountrySalesChart() {
    const chart = echarts.init(document.getElementById('countrySalesChart'));
    axios.get(`${API_BASE_URL}/api/country_sales_distribution/list`)
        .then(res => {
            // 与后端返回结构保持一致
            const list = (res.data?.data) || [];

            // 构造饼图需要的 { name, value } 数组
            const pieData = list.map(item => ({
                name: item.country,          // 国家名
                value: item.countryRevenue   // 销售额
            }));

            const option = {
                backgroundColor: 'transparent',
                tooltip: {
                    trigger: 'item',
                    formatter: '{b}<br/>¥{c} ({d}%)'
                },
                legend: {
                    orient: 'vertical',
                    right: '5%',
                    top: 'center',
                    textStyle: { color: '#e0e0e0' }
                },
                series: [{
                    name: '各国销售额',
                    type: 'pie',
                    radius: ['35%', '70%'],   // 内外半径 → 环形
                    center: ['40%', '50%'],   // 左右、上下居中
                    data: pieData,
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    },
                    label: {
                        color: '#fff',
                        formatter: '{b}: {d}%'
                    },
                    labelLine: {
                        lineStyle: { color: '#fff' }
                    },
                    itemStyle: {
                        // 彩虹渐变示例，可按需替换
                        color: function (params) {
                            const colors = [
                                '#5470c6', '#91cc75', '#fac858',
                                '#ee6666', '#73c0de', '#3ba272',
                                '#fc8452', '#9a60b4', '#ea7ccc'
                            ];
                            return colors[params.dataIndex % colors.length];
                        }
                    }
                }]
            };

            chart.setOption(option);
            window.addEventListener('resize', () => chart.resize());
        })
        .catch(err => console.error('国家销售分布数据失败:', err));
}

    /* 6. 单价 vs 销量 散点图 */
function initPriceSalesChart() {
    const chart = echarts.init(document.getElementById('priceSalesChart'));
    axios.get(`${API_BASE_URL}/api/price_sales_relation/list`)
        .then(res => {
            const data = (res.data?.data) || [];

            /* 1. 计算总范围，用于滑条两端的常亮区间 */
            const xList = data.map(d => d.unitPrice);
            const yList = data.map(d => d.totalQuantity);
            const xMin = Math.min(...xList);
            const xMax = Math.max(...xList);
            const yMin = Math.min(...yList);
            const yMax = Math.max(...yList);

            /* 2. ECharts 配置 */
            const option = {
                backgroundColor: 'transparent',
                grid: { left: 80, right: 80, bottom: 100, top: 40, containLabel: true },
                tooltip: {
                    trigger: 'item',
                    formatter: p =>
                        `单价: ¥${p.data[0].toFixed(2)}<br/>` +
                        `销量: ${p.data[1].toLocaleString()} 件<br/>` +
                        `销售额: ¥${(p.data[0] * p.data[1]).toFixed(2)}`
                },
                xAxis: {
                    type: 'value',
                    min: xMin,
                    max: xMax,
                    name: '平均单价',
                    nameTextStyle: { color: '#ccc' },
                    axisLine: { lineStyle: { color: '#aaa' } },
                    axisLabel: { color: '#ccc', formatter: '¥{value}' },
                    splitLine: { lineStyle: { color: 'rgba(255,255,255,.1)' } }
                },
                yAxis: {
                    type: 'value',
                    min: yMin,
                    max: yMax,
                    name: '销售数量',
                    axisLine: { lineStyle: { color: '#aaa' } },
                    axisLabel: { color: '#ccc' },
                    splitLine: { lineStyle: { color: 'rgba(255,255,255,.1)' } }
                },
                /* 3. 放大按钮 & 常亮区间 */
                dataZoom: [
                    {
                        type: 'slider',
                        xAxisIndex: 0,
                        height: 20,                         // 滑条整体更高
                        bottom: 20,
                        borderColor: 'rgba(255,255,255,.3)',
                        fillerColor: 'rgba(255,183,77,.4)', // 选中区域高亮
                        handleSize: 60,                     // 手柄更大
                        handleStyle: {
                            color: '#ffb74d',
                            borderWidth: 3,
                            borderColor: '#fff'
                        },
                        textStyle: { color: '#fff' },
                        showDetail: true                    // 显示当前数值
                    },
                    {
                        type: 'slider',
                        yAxisIndex: 0,
                        width: 20,                          // 滑条整体更宽
                        left: 20,
                        borderColor: 'rgba(255,255,255,.3)',
                        fillerColor: 'rgba(255,183,77,.4)',
                        handleSize: 60,
                        handleStyle: {
                            color: '#ffb74d',
                            borderWidth: 3,
                            borderColor: '#fff'
                        },
                        textStyle: { color: '#fff' },
                        showDetail: true
                    }
                ],
                series: [{
                    name: '商品平均单价与销售关系',
                    type: 'scatter',
                    data: data.map(i => [i.unitPrice, i.totalQuantity]),
                    itemStyle: { color: '#ffb74d' },
                    large: true,
                    largeThreshold: 2000
                }]
            };
            chart.setOption(option);
            window.addEventListener('resize', () => chart.resize());
        })
        .catch(err => console.error('单价销量关系数据失败:', err));
}

    /* ---------- 启动 ---------- */
    initNavigation();
    initPageCharts(currentPage);
</script>
</body>
</html>